package noth.li.sgs.utils;

import noth.li.sgs.card.BasicCard;
import noth.li.sgs.card.HolderCard;
import noth.li.sgs.card.equipment.WeaponCard;
import noth.li.sgs.hero.BaseHero;

import java.util.*;

/**
 * 工具类
 */
public class CommonUtil {


    /**
     * 将手牌转成提示的功能
     *
     * @param cards 需要转的手牌集合
     * @return
     */
    public static String showCardsName(List<HolderCard> cards) {
        StringBuilder sb = new StringBuilder("【");
        cards.stream().forEach(item -> {
            sb.append(item.toString()).append(",");
        });
        return sb.substring(0, sb.length() - 1) + "】";
    }

    /**
     * 判断一个对象是否为空
     *
     * @param o 被判断的对象
     * @return true--为空  false--不为空
     */
    public static boolean isEmpty(Object o) {
        if (o == null)
            return true;
        if (o instanceof List)
            return ((List) o).size() <= 0 ? true : false;
        if (o instanceof Map)
            return ((Map) o).isEmpty();
        if (o instanceof String)
            return ((String) o).isEmpty();
        if (o instanceof Object[]) {
            if (((Object[]) o).length == 0)
                return true;
            else {
                boolean allNullFlg = true;
                for (Object obj : ((Object[]) o)) {
                    if (isNotEmpty(obj)) {
                        allNullFlg = false;
                        break;
                    }
                }
                return allNullFlg;
            }
        }
        if (o instanceof Stack)
            return (((Stack) o).isEmpty());
        return false;
    }

    /**
     * 判断一个对象是否不为空
     *
     * @param o 被判断的对象
     * @return true--不为空  false--空
     */
    public static boolean isNotEmpty(Object o) {
        return !isEmpty(o);
    }

    /**
     * 摸牌阶段-武将摸牌的方法
     *
     * @param original 摸牌的牌堆
     * @param hero     摸牌的武将
     * @param mcount   摸牌的数量
     */
    public static void getCards(List<HolderCard> original, BaseHero hero, int mcount) {
        StringBuilder sb = new StringBuilder(hero.getName() + "从牌堆顶摸了" + mcount + "张牌,【");
        Iterator<HolderCard> it = original.iterator();
        int count = 1;
        while (it.hasNext()) {
            if (count == (mcount + 1))
                break;
            HolderCard c = it.next();
            hero.acceptCards(c);
            sb.append(c.toString() + ",");
            count++;
            it.remove();
        }
        System.out.println(sb.substring(0, sb.length() - 1) + "】");
    }

    /**
     * 判定阶段-获取牌堆顶判定牌的方法
     * 获取玩牌堆顶的牌，判定完成后需要将牌加载到弃牌堆中
     *
     * @param original 牌堆
     * @return 判定牌
     */
    public static HolderCard getPdCard(List<HolderCard> original) {
        Iterator<HolderCard> it = original.iterator();
        while (it.hasNext()) {
            HolderCard c = it.next();
            it.remove();
            return c;
        }
        return null;
    }

    /**
     * 获取场上存活武将的名称列表
     *
     * @param alives    存活的武将
     * @param myself    执行阶段武将的自己
     * @param removeFlg 是否移除myself true-移除 false-不移除
     * @return 存活武将的名称列表
     */
    public static String getAliveHeroNames(List<BaseHero> alives, BaseHero myself, boolean removeFlg) {
        StringBuilder sb = new StringBuilder("可选择成为目标的武将==>【");
        for (BaseHero h : alives) {
            if (removeFlg && (!(myself.getName().equals(h.getName()))))
                sb.append(h.getName() + ",");
        }
        return sb.substring(0, sb.length() - 1) + "】";
    }


    /**
     * 当玩家确定出牌时
     * 检验武将手牌中是否有该牌
     *
     * @param sc            交互类
     * @param localHero     使用牌的武将
     * @param checkCardName 校验牌的名称
     * @return 如果有则返回使用的牌, 如没有返回null
     */
    public static HolderCard checkCardMessage(Scanner sc, BaseHero localHero, String checkCardName) {
        HolderCard useCard = null;
        while (true) {
            System.out.println(localHero.getName() + "的手牌为==>" + CommonUtil.showCardsName(localHero.getHoldCards()));
            System.out.println("方片-1、梅花-2、红桃-3、黑桃-4");
            System.out.println("例如♦2桃的输入方式为:12桃");
            System.out.print("请输入" + localHero.getName() + "要使用的牌:");
            String cardNum = sc.nextLine();
            if (!(cardNum.startsWith("1") || cardNum.startsWith("2") || cardNum.startsWith("3") || cardNum.startsWith("4"))) {
                System.out.println(localHero.getName() + "的输入不符合规则!");
                continue;
            }

            //由于使用的牌可能是多张,此处要加判断
            String[] names = checkCardName.split(",");
            boolean flg = false;

            for (String name : names) {
                if (!(cardNum.endsWith(name)))
                    flg = true;
                else
                    flg = false;
            }


            if (flg) {
                System.out.println(localHero.getName() + "的输入不符合规则!");
                continue;
            }

            char[] chars = cardNum.toCharArray(); //牌名的具体展示

            if ('1' == chars[0]) {
                chars[0] = '♦';
            } else if ('2' == chars[0]) {
                chars[0] = '♣';
            } else if ('3' == chars[0]) {
                chars[0] = '♡';
            } else if ('4' == chars[0]) {
                chars[0] = '♤';
            }

            boolean hasCardFlg = false; //是否有当前输入的手牌
            for (HolderCard h : localHero.getHoldCards()) {
                //点数为10,必须加以判断
                if (chars.length == 4) {
                    if (h.getDecor().equals(chars[0] + "") && h.getPointAlsa().equals("" + chars[1] + chars[2]) && h.getBrandName().equals(chars[3] + "")) {
                        hasCardFlg = true;
                        useCard = h;
                        break;
                    }

                } else {
                    if (h.getDecor().equals(chars[0] + "") && h.getPointAlsa().equals("" + chars[1]) && h.getBrandName().equals(chars[2] + "")) {
                        hasCardFlg = true;
                        useCard = h;
                        break;
                    }
                }
            }

            if (!hasCardFlg) {
                System.out.println(localHero.getName() + "手牌中不包含输入的牌,请重新输入!");
                continue;
            } else
                break;
        }
        return useCard;
    }

    /**
     * 根据武将姓名获得存活武将池中的武将
     *
     * @param heroName
     * @param aliveHeroes
     * @return 武将
     */
    public static BaseHero getHeroByName(String heroName, List<BaseHero> aliveHeroes) {
        for (BaseHero hero : aliveHeroes) {
            if (heroName.equals(hero.getName()))
                return hero;
        }
        return null;
    }

    /**
     * 调用武器技能的方法
     *
     * @param weapon     武器牌
     * @param owner      武器所有者
     * @param goalHero   目标武将
     * @param bc         武器作用的基本牌
     * @param sc         交互工具
     * @param throwCards 弃牌堆
     */
    public static Object weaponFunction(WeaponCard weapon, BaseHero owner, BaseHero goalHero, HolderCard bc, Scanner sc, List<HolderCard> throwCards) {
        if ("诸葛连弩".equals(weapon.getBrandName())) {
            System.out.println(owner.getName() + "发动了" + weapon.getBrandName());
            return true;
        } else if ("朱雀羽扇".equals(weapon.getBrandName())) {
            int huoShaCount = 0;
            //判断武将身上是否穿了藤甲,如果穿了,火杀伤害+1
            if (CommonUtil.isNotEmpty(goalHero.getArmor()) && "藤甲".equals(goalHero.getArmor().getBrandName())) {
                System.out.println(goalHero.getName() + "发动了藤甲...");
                if ((((BasicCard) bc).isFireShaFlg()))
                    huoShaCount++;
                //如果是朱雀羽扇发动的,将火杀标识重置
                if (CommonUtil.isNotEmpty(owner.getWeapon()) && "朱雀羽扇".equals(owner.getWeapon())) {
                    ((BasicCard) bc).setFireShaFlg(false);
                }
            }
            return huoShaCount;
        } else if ("麒麟弓".equals(weapon.getBrandName())) {

            System.out.print(owner.getName() + "是否发动麒麟弓,弃置" + goalHero.getName() + "装备区的坐骑牌?(0-否,1-是):");
            String an = sc.nextLine();
            while (true) {
                if (!("0".equals(an) || "1".equals(an))) {
                    System.out.println("请输入正确的操作!");
                    continue;
                }
                break;
            }
            if ("1".equals(an)) {
                if (goalHero.getHorses().length == 1) {
                    if (CommonUtil.isNotEmpty(goalHero.getHorses()[0])) {
                        System.out.println(owner.getName() + "发动了麒麟弓,弃置了" + goalHero.getName() + "的坐骑牌" + goalHero.getHorses()[0]);
                        throwCards.add(goalHero.getHorses()[0]);
                        goalHero.getHorses()[0] = null;
                    } else if (CommonUtil.isNotEmpty(goalHero.getHorses()[1])) {
                        System.out.println(owner.getName() + "发动了麒麟弓,弃置了" + goalHero.getName() + "的坐骑牌" + goalHero.getHorses()[1]);
                        throwCards.add(goalHero.getHorses()[1]);
                        goalHero.getHorses()[1] = null;
                    }
                } else if (goalHero.getHorses().length == 2) {
                    System.out.print("请输入弃置的坐骑牌。(0->+1马,1->-1马):");
                    an = sc.nextLine();
                    while (true) {
                        if (!("0".equals(an) || "1".equals(an))) {
                            System.out.println("请输入正确的操作!");
                            continue;
                        }
                        break;
                    }
                    if ("0".equals(an)) {
                        /**
                         * getHorses()[0] --- +1马
                         * getHorses()[1] --- 进攻马
                         */
                        System.out.println(owner.getName() + "发动了麒麟弓,弃置了" + goalHero.getName() + "的坐骑牌" + goalHero.getHorses()[0]);
                        throwCards.add(goalHero.getHorses()[0]);
                        goalHero.getHorses()[0] = null;
                    } else if ("1".equals(an)) {
                        /**
                         * getHorses()[0] --- +1马
                         * getHorses()[1] --- 进攻马
                         */
                        System.out.println(owner.getName() + "发动了麒麟弓,弃置了" + goalHero.getName() + "的坐骑牌" + goalHero.getHorses()[1]);
                        throwCards.add(goalHero.getHorses()[1]);
                        goalHero.getHorses()[1] = null;
                    }
                }
            }

        }

        return null;
    }
}
